package com.chenhao.generator.util;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * 文件工具
 *
 * @author:chenHao
 * @version:1.0
 * @since:1.0
 * @createTime:2019-10-03
 */
public class FileUtil {


    /**
     * 获取所有资源
     *
     * @param clazz
     * @param nameStart
     * @return java.lang.String[]
     * @author chenHao
     * @date 2019-10-03
     **/
    public static String[] getResources(Class clazz, String nameStart) throws IOException {
        Set resources = new HashSet();
        String classResourceName = clazz.getName().replace(".", "/") + ".class";
        URL classResourceURL = clazz.getClassLoader().getResource(classResourceName);
        String classResourcePath = classResourceURL.getPath();
        if (classResourceURL.getProtocol().equals("file")) {
            // 开发环境里class和resource同位于target/classes目录下
            String classesDirPath = classResourcePath.substring(classResourcePath.indexOf("/") + 1, classResourcePath
                    .indexOf(classResourceName));
            File classesDir = new File(classesDirPath);
            List<File> files = enumerateDir(classesDir);
            for (File file : files) {
                String resourceName = file.getAbsolutePath();
                resourceName = resourceName.substring(classesDirPath.length());
                resourceName = resourceName.replace("//", "/");
                resourceName = resourceName.replace("\\", "/");
                if (!file.isDirectory() && resourceName.startsWith(nameStart)) {
                    resources.add(resourceName);
                }
            }
        } else if (classResourceURL.getProtocol().equals("jar")) {
            // 打包成jar包时,class和resource同位于jar包里
            String jarPath = classResourcePath.substring(classResourcePath.indexOf("/"), classResourceURL.getPath().indexOf("!"));
            try {
                JarFile jarFile = new JarFile(URLDecoder.decode(jarPath, "UTF-8"));
                Enumeration jarEntries = jarFile.entries();
                while (jarEntries.hasMoreElements()) {
                    JarEntry jarEntry = (JarEntry) jarEntries.nextElement();
                    String resourceName = jarEntry.getName();
                    if (!jarEntry.isDirectory() && resourceName.contains(nameStart)) {
                        resources.add(resourceName.replace("BOOT-INF/classes", ""));
                    }
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return (String[]) resources.toArray(new String[0]);
    }

    /**
     * 递归查询所有文件
     *
     * @param dir
     * @return java.util.List
     * @author chenHao
     * @date 2019-10-03
     **/
    public static List enumerateDir(File dir) {
        List<File> fileList = new ArrayList();
        if (dir == null) {

        } else if (dir.isDirectory()) {
            File[] subFiles = dir.listFiles();
            for (File subFile : subFiles) {
                fileList.add(subFile);
                if (subFile.isDirectory()) {
                    fileList.addAll(enumerateDir(subFile));
                }
            }
        } else {
            fileList.add(dir);
        }
        return fileList;
    }


    public static boolean delFile(File file) {
        if (!file.exists()) {
            return false;
        }

        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (File f : files) {
                delFile(f);
            }
        }
        return file.delete();
    }

    /**
     * 递归查询目录下所有文件
     *
     * @param dir
     * @param fileList
     * @return void
     * @author chenHao
     * @date 2019-10-03
     **/
    public static void findFileList(File dir, List<File> fileList) {
        // 判断是否存在目录
        if (!dir.exists() || !dir.isDirectory()) {
            return;
        }
        // 读取目录下的所有目录文件信息
        String[] files = dir.list();
        // 循环，添加文件名或回调自身
        for (int i = 0; i < files.length; i++) {
            File file = new File(dir, files[i]);
            if (file.isFile()) {
                // 如果文件 添加文件全路径名
                fileList.add(file);
            } else {
                // 如果是目录  回调自身继续查询
                findFileList(file, fileList);
            }
        }
    }
}
